package com.yilizhiyou.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yilizhiyou.entity.ScenicSpot;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.math.BigDecimal;
import java.util.List;

/**
 * 景区Mapper接口
 * 
 * @author 伊犁智游开发团队
 * @since 1.0.0
 */
@Mapper
public interface ScenicSpotMapper extends BaseMapper<ScenicSpot> {

    /**
     * 分页查询景区列表
     * 
     * @param page 分页参数
     * @param name 景区名称（模糊查询）
     * @param type 景区类型
     * @param status 景区状态
     * @return 景区列表
     */
    @Select("<script>" +
            "SELECT * FROM scenic_spot WHERE deleted = 0 " +
            "<if test='name != null and name != \"\"'>" +
            "AND name LIKE CONCAT('%', #{name}, '%') " +
            "</if>" +
            "<if test='type != null'>" +
            "AND type = #{type} " +
            "</if>" +
            "<if test='status != null'>" +
            "AND status = #{status} " +
            "</if>" +
            "ORDER BY popularity DESC, create_time DESC" +
            "</script>")
    IPage<ScenicSpot> findScenicSpotPage(Page<ScenicSpot> page, 
                                        @Param("name") String name, 
                                        @Param("type") Integer type, 
                                        @Param("status") Integer status);

    /**
     * 根据位置查询附近景区
     * 
     * @param longitude 经度
     * @param latitude 纬度
     * @param radius 半径（公里）
     * @param limit 限制数量
     * @return 附近景区列表
     */
    @Select("SELECT *, " +
            "(6371 * acos(cos(radians(#{latitude})) * cos(radians(latitude)) * " +
            "cos(radians(longitude) - radians(#{longitude})) + " +
            "sin(radians(#{latitude})) * sin(radians(latitude)))) AS distance " +
            "FROM scenic_spot " +
            "WHERE deleted = 0 AND status = 1 " +
            "HAVING distance <= #{radius} " +
            "ORDER BY distance ASC " +
            "LIMIT #{limit}")
    List<ScenicSpot> findNearbyScenicSpots(@Param("longitude") BigDecimal longitude,
                                          @Param("latitude") BigDecimal latitude,
                                          @Param("radius") double radius,
                                          @Param("limit") int limit);

    /**
     * 查询热门景区
     * 
     * @param limit 限制数量
     * @return 热门景区列表
     */
    @Select("SELECT * FROM scenic_spot WHERE deleted = 0 AND status = 1 " +
            "ORDER BY popularity DESC, recommend_score DESC " +
            "LIMIT #{limit}")
    List<ScenicSpot> findPopularScenicSpots(@Param("limit") int limit);

    /**
     * 根据类型查询景区
     * 
     * @param type 景区类型
     * @param limit 限制数量
     * @return 景区列表
     */
    @Select("SELECT * FROM scenic_spot WHERE deleted = 0 AND status = 1 AND type = #{type} " +
            "ORDER BY popularity DESC " +
            "LIMIT #{limit}")
    List<ScenicSpot> findScenicSpotsByType(@Param("type") Integer type, @Param("limit") int limit);

    /**
     * 搜索景区
     * 
     * @param keyword 关键词
     * @param limit 限制数量
     * @return 搜索结果
     */
    @Select("SELECT * FROM scenic_spot WHERE deleted = 0 AND status = 1 " +
            "AND (name LIKE CONCAT('%', #{keyword}, '%') " +
            "OR description LIKE CONCAT('%', #{keyword}, '%') " +
            "OR tags LIKE CONCAT('%', #{keyword}, '%')) " +
            "ORDER BY popularity DESC " +
            "LIMIT #{limit}")
    List<ScenicSpot> searchScenicSpots(@Param("keyword") String keyword, @Param("limit") int limit);

    /**
     * 更新景区人气指数
     * 
     * @param id 景区ID
     * @param popularity 人气指数
     */
    @Select("UPDATE scenic_spot SET popularity = popularity + #{popularity} WHERE id = #{id}")
    void updatePopularity(@Param("id") Long id, @Param("popularity") Integer popularity);
}
